/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.io.output; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; import junit.framework.TestCase; /** * Unit tests for the <code>DeferredFileOutputStream</code> class. * * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> * * @version $Id: DeferredFileOutputStreamTest.java 606381 2007-12-22 02:03:16Z ggregory $ */ public class DeferredFileOutputStreamTest extends TestCase { /** * The test data as a string (which is the simplest form). */ private String testString = "0123456789"; /** * The test data as a byte array, derived from the string. */ private byte[] testBytes = testString.getBytes(); /** * Standard JUnit test case constructor. * * @param name The name of the test case. */ public DeferredFileOutputStreamTest(String name) { super(name); } /** * Tests the case where the amount of data falls below the threshold, and * is therefore confined to memory. */ public void testBelowThreshold() { DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length + 42, null); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertTrue(dfos.isInMemory()); byte[] resultBytes = dfos.getData(); assertTrue(resultBytes.length == testBytes.length); assertTrue(Arrays.equals(resultBytes, testBytes)); } /** * Tests the case where the amount of data is exactly the same as the * threshold. The behavior should be the same as that for the amount of * data being below (i.e. not exceeding) the threshold. */ public void testAtThreshold() { DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length, null); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertTrue(dfos.isInMemory()); byte[] resultBytes = dfos.getData(); assertTrue(resultBytes.length == testBytes.length); assertTrue(Arrays.equals(resultBytes, testBytes)); } /** * Tests the case where the amount of data exceeds the threshold, and is * therefore written to disk. The actual data written to disk is verified, * as is the file itself. */ public void testAboveThreshold() { File testFile = new File("testAboveThreshold.dat"); // Ensure that the test starts from a clean base. testFile.delete(); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length - 5, testFile); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); verifyResultFile(testFile); // Ensure that the test starts from a clean base. testFile.delete(); } /** * Tests the case where there are multiple writes beyond the threshold, to * ensure that the <code>thresholdReached()</code> method is only called * once, as the threshold is crossed for the first time. */ public void testThresholdReached() { File testFile = new File("testThresholdReached.dat"); // Ensure that the test starts from a clean base. testFile.delete(); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length / 2, testFile); int chunkSize = testBytes.length / 3; try { dfos.write(testBytes, 0, chunkSize); dfos.write(testBytes, chunkSize, chunkSize); dfos.write(testBytes, chunkSize * 2, testBytes.length - chunkSize * 2); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); verifyResultFile(testFile); // Ensure that the test starts from a clean base. testFile.delete(); } /** * Test wether writeTo() properly writes small content. */ public void testWriteToSmall(){ File testFile = new File("testWriteToMem.dat"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Ensure that the test starts from a clean base. testFile.delete(); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length *2, testFile); try{ dfos.write(testBytes); assertFalse(testFile.exists()); assertTrue(dfos.isInMemory()); try { dfos.writeTo(baos); fail("Should not have been able to write before closing"); } catch (IOException ioe) { // ok, as expected } dfos.close(); dfos.writeTo(baos); } catch (IOException ioe) { fail("Unexpected IOException"); } byte[] copiedBytes = baos.toByteArray(); assertTrue(Arrays.equals(testBytes, copiedBytes)); testFile.delete(); } /** * Test wether writeTo() properly writes large content. */ public void testWriteToLarge(){ File testFile = new File("testWriteToFile.dat"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Ensure that the test starts from a clean base. testFile.delete(); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length /2, testFile); try{ dfos.write(testBytes); assertTrue(testFile.exists()); assertFalse(dfos.isInMemory()); try { dfos.writeTo(baos); fail("Should not have been able to write before closeing"); } catch (IOException ioe) { // ok, as expected } dfos.close(); dfos.writeTo(baos); } catch (IOException ioe) { fail("Unexpected IOException"); } byte[] copiedBytes = baos.toByteArray(); assertTrue(Arrays.equals(testBytes, copiedBytes)); verifyResultFile(testFile); testFile.delete(); } /** * Test specifying a temporary file and the threshold not reached. */ public void testTempFileBelowThreshold() { String prefix = "commons-io-test"; String suffix = ".out"; File tempDir = new File("."); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length + 42, prefix, suffix, tempDir); assertNull("Check file is null-A", dfos.getFile()); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertTrue(dfos.isInMemory()); assertNull("Check file is null-B", dfos.getFile()); } /** * Test specifying a temporary file and the threshold is reached. */ public void testTempFileAboveThreshold() { String prefix = "commons-io-test"; String suffix = ".out"; File tempDir = new File("."); DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length - 5, prefix, suffix, tempDir); assertNull("Check file is null-A", dfos.getFile()); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); assertNotNull("Check file not null", dfos.getFile()); assertTrue("Check file exists", dfos.getFile().exists()); assertTrue("Check prefix", dfos.getFile().getName().startsWith(prefix)); assertTrue("Check suffix", dfos.getFile().getName().endsWith(suffix)); assertEquals("Check dir", tempDir.getPath(), dfos.getFile().getParent()); verifyResultFile(dfos.getFile()); // Delete the temporary file. dfos.getFile().delete(); } /** * Test specifying a temporary file and the threshold is reached. */ public void testTempFileAboveThresholdPrefixOnly() { String prefix = "commons-io-test"; String suffix = null; File tempDir = null; DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length - 5, prefix, suffix, tempDir); assertNull("Check file is null-A", dfos.getFile()); try { dfos.write(testBytes, 0, testBytes.length); dfos.close(); } catch (IOException e) { fail("Unexpected IOException"); } assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); assertNotNull("Check file not null", dfos.getFile()); assertTrue("Check file exists", dfos.getFile().exists()); assertTrue("Check prefix", dfos.getFile().getName().startsWith(prefix)); assertTrue("Check suffix", dfos.getFile().getName().endsWith(".tmp")); // ".tmp" is default verifyResultFile(dfos.getFile()); // Delete the temporary file. dfos.getFile().delete(); } /** * Test specifying a temporary file and the threshold is reached. */ public void testTempFileError() { String prefix = null; String suffix = ".out"; File tempDir = new File("."); try { DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length - 5, prefix, suffix, tempDir); fail("Expected IllegalArgumentException "); } catch (IllegalArgumentException e) { // expected } } /** * Verifies that the specified file contains the same data as the original * test data. * * @param testFile The file containing the test output. */ private void verifyResultFile(File testFile) { try { FileInputStream fis = new FileInputStream(testFile); assertTrue(fis.available() == testBytes.length); byte[] resultBytes = new byte[testBytes.length]; assertTrue(fis.read(resultBytes) == testBytes.length); assertTrue(Arrays.equals(resultBytes, testBytes)); assertTrue(fis.read(resultBytes) == -1); try { fis.close(); } catch (IOException e) { // Ignore an exception on close } } catch (FileNotFoundException e) { fail("Unexpected FileNotFoundException"); } catch (IOException e) { fail("Unexpected IOException"); } } }